package com.qyxx.platform.common.module.web;

import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.opensymphony.xwork2.Preparable;
import com.qyxx.platform.common.orm.Page;

/**
 * Struts2中典型CRUD Action的抽象基类.
 * 
 * 主要定义了对Preparable,ModelDriven接口的使用,以及CRUD函数和返回值的命名.
 *
 * @param <T> CRUDAction所管理的对象类型.
 * 
 * @author calvin
 */
public abstract class CrudActionSupport<T> extends ActionSupport implements ModelDriven<T>, Preparable {

	/** 进行增删改操作后,以redirect方式重新打开action默认页的result名.*/
	public static final String RELOAD = "reload";
	
	/** 查看操作需返回的值  */
	public static final String VIEW = "view";
	
	/** 新增操作需返回的值  */
	public static final String ADD = "add";
	
	/** 修改操作需返回的值  */
	public static final String EDIT = "edit";
	/**查询子表跳转页面*/
	public static final String VIEW_SUB = "view_sub";
	
	public static final String PARENTCODE = "autoParentCode";
	
	public static final String PARENTID = "_parentId";
	
	private static final long serialVersionUID = -1653204626115064950L;

	protected Logger logger = LoggerFactory.getLogger(getClass());

	/** 排序方向  */
	protected String order = "desc";
	
	/** 排序字段 */
	protected String sort = "id";
	
	/** 页码 */
	protected int page = 1;
	
	/** 每页记录数 */
	protected int rows = 10;
	
	/** 分页对象 */
	protected Page<T> pager = new Page<T>(10);//每页10条记录
	
	/** 返回消息对象 */
	protected FormatMessage formatMessage = new FormatMessage();
	
	/** 主对象ID */
	protected Long id;
	
	/** 主对象ID数组 */
	protected Long[] ids;


	/** 主对象ID字符串，逗号隔开*/
	protected String idsStr;
	
	/** 主对象实体 */
	protected T entity;
	
	/**
	 * 设置ID
	 * 
	 * @param id
	 */
	public void setId(Long id) {
		this.id = id;
	}
	
	/**
	 * @return id
	 */
	public Long getId() {
		return id;
	}

	
	/**
	 * @return ids
	 */
	public Long[] getIds() {
		return ids;
	}


	/**
	 * @param ids
	 */
	public void setIds(Long[] ids) {
		this.ids = ids;
	}


	public String getIdsStr() {
		return idsStr;
	}

	public void setIdsStr(String idsStr) {
		this.idsStr = idsStr;
	}


	/**
	 * 获取实体
	 * @see com.opensymphony.xwork2.ModelDriven#getModel()
	 */
	@Override
	public T getModel() {
		return entity;
	}

	/**
	 * @return order
	 */
	public String getOrder() {
		return order;
	}

	
	/**
	 * @param order
	 */
	public void setOrder(String order) {
		this.order = order;
		pager.setOrder(order);
	}

	
	/**
	 * @return sort
	 */
	public String getSort() {
		return sort;
	}

	
	/**
	 * @param sort
	 */
	public void setSort(String sort) {
		this.sort = sort;
		pager.setOrderBy(sort);
	}

	
	/**
	 * @return page
	 */
	public int getPage() {
		return page;
	}

	
	/**
	 * @param page
	 */
	public void setPage(int page) {
		this.page = page;
		pager.setPageNo(page);
	}

	
	/**
	 * @return rows
	 */
	public int getRows() {
		return rows;
	}

	
	/**
	 * @param rows
	 */
	public void setRows(int rows) {
		this.rows = rows;
		pager.setPageSize(rows);
	}

	
	/**
	 * @return pager
	 */
	public Page<T> getPager() {
		return pager;
	}


	
	/**
	 * @param pager
	 */
	public void setPager(Page<T> pager) {
		this.pager = pager;
	}


	
	/**
	 * @return formatMessage
	 */
	public FormatMessage getFormatMessage() {
		return formatMessage;
	}


	
	/**
	 * @param formatMessage
	 */
	public void setFormatMessage(FormatMessage formatMessage) {
		this.formatMessage = formatMessage;
	}


	/**
	 * Action函数, 默认的action函数, 默认调用list()函数.
	 */
	@Override
	public String execute() throws Exception {
		return list();
	}

	//-- CRUD Action函数 --//
	/**
	 * Action函数,显示Entity列表界面.
	 * 建议return SUCCESS.
	 */
	public abstract String list() throws Exception;

	/**
	 * Action函数,显示新增或修改Entity界面.
	 * 建议return INPUT.
	 */
	@Override
	public abstract String input() throws Exception;

	/**
	 * Action函数,新增或修改Entity. 
	 * 建议return RELOAD.
	 */
	public abstract String save() throws Exception;

	/**
	 * Action函数,查看Entity. 
	 * 建议return RELOAD.
	 */
	public abstract String view() throws Exception;
	
	/**
	 * Action函数,删除Entity.
	 * 建议return RELOAD.
	 */
	public abstract String delete() throws Exception;

	//-- Preparable函数 --//
	/**
	 * 实现空的prepare()函数,屏蔽了所有Action函数都会执行的公共的二次绑定.
	 */
	public void prepare() throws Exception {
	}

	/**
	 * 定义在input()前执行二次绑定.
	 */
	public void prepareInput() throws Exception {
		prepareModel();
	}

	/**
	 * 定义在save()前执行二次绑定.
	 */
	public void prepareSave() throws Exception {
		prepareModel();
	}

	/**
	 * 定义在view()前执行二次绑定.
	 */
	public void prepareView() throws Exception {
		prepareModel();
	}
	
	/**
	 * 等同于prepare()的内部函数,供prepardMethodName()函数调用. 
	 */
	protected abstract void prepareModel() throws Exception;
	
	/**
	 * 预处理page对象，去掉不需显示的属性
	 * 
	 * @param pageObj 分页对象
	 * @param filterProp 过滤属性的名称
	 */
	protected void preHandleObject(Page<Map<String, Object>> pageObj, List<String> filterProp) {
		List<Map<String,Object>> tmpList = pageObj.getResult();
		for(Map<String, Object> obj : tmpList) {
			Object o = obj.get(PARENTCODE);
			if(o!=null){
				obj.put(PARENTID,o);
			}
			for(String filterKey : filterProp) {
				obj.remove(filterKey);				
			}
		}
	}
	
	/**
	 * 预处理Map对象，去掉不需显示的属性
	 * 
	 * @param obj 实体Map对象
	 * @param filterProp 过滤属性的名称
	 */
	protected void preHandleObject(Map<String, Object> obj, List<String> filterProp) {
		for(String filterKey : filterProp) {
			obj.remove(filterKey);
		}
	}
	
}
